package com.feng
{
	import com.feng.behavior.AttackBehavior;
	import com.feng.behavior.BehaviorCompute;
	import com.feng.behavior.BehaviorControler;
	import com.feng.behavior.DefenseBehavior;
	import com.feng.data.StateData;
	import com.feng.debug.logger;
	import com.feng.debug.logger1;
	import com.feng.model.EnmityRecord;
	import com.feng.model.Player;
	import com.feng.stateAnalysis.AttackMaxAnalysis;
	import com.feng.stateAnalysis.AttackOrderAnalysis;
	import com.feng.stateAnalysis.KillStealAnalysis;
	import com.feng.stateAnalysis.MultiplayerAnalysis;
	import com.feng.stateAnalysis.ThreeAnalysis;
	import com.feng.strategy.StrategyManager;
	
	import flash.utils.Dictionary;

	/**
	 * 控制中心
	 * @author 风之守望者
	 * 2013-3-29
	 */
	public class ControllerCenter
	{
		/** 当前状态的数据 */
		public var stateData:StateData;

		/** 攻击行为 */
		public var attackBehavior:AttackBehavior;

		/** 防御行为 */
		public var defenseBehavior:DefenseBehavior;

		/** 行为控制中心 */
		public var behaviorControler:BehaviorControler;

		/** 策略管理 */
		public var strategyManager:StrategyManager;

		/** 行为计算 */
		public var behaviorCompute:BehaviorCompute;

		/** 三人模式下形势分析 */
		public var threeStateAnalysis:ThreeAnalysis;

		/** 多人模式形势分析 */
		public var multiplayerAnalysis:MultiplayerAnalysis;

		/** 抢人头形势分析 */
		public var killStealAnalysis:KillStealAnalysis;

		/** 攻击顺序分析 */
		public var attackOrderAnalysis:AttackOrderAnalysis;

		public var attackMaxAnalysis:AttackMaxAnalysis;
		
		public function ControllerCenter()
		{
			//初始化数据
			stateData = new StateData();

			//初始化行为
			attackBehavior = new AttackBehavior(this);
			defenseBehavior = new DefenseBehavior(this);
			behaviorControler = new BehaviorControler(this);

			//初始化策略
			strategyManager = new StrategyManager(this);

			//初始化形势分析
			threeStateAnalysis = new ThreeAnalysis(this);

			multiplayerAnalysis = new MultiplayerAnalysis(this);

			killStealAnalysis = new KillStealAnalysis(this);

			attackOrderAnalysis = new AttackOrderAnalysis(this);
			
			attackMaxAnalysis = new AttackMaxAnalysis(this);

			//初始化 最终行为计算
			behaviorCompute = new BehaviorCompute(this);
		}

		/**
		 *  //轮到你行动时会被调用。
		 //在一场战斗中，你已经死亡或者已经胜利不会继续被调用。
		 //参数state，返回所有程序员的状态，格式如[{id:0,hp:150,atk:20,def:0,spd:10},{id:1,hp:170,atk:12,def:12,spd:10}, ...]。
		 //在一次战斗中，state中玩家的顺序不改变，死人会以hp=0的状态存在state里。顺序序号始终等于数组中的id值。
		 //参数myId，我的id，自己是数组中的第几位。
		 //返回值：一个整形。你要攻击的目标序号。
		 //返回自己、返回已经空血的人、返回不存在的序号都视为攻击自己。
		 */
		public function onAttack(state:Array, myId:int):int
		{
			logger(JSON.stringify(state)+",myId:"+myId);
			//更新数据
			stateData.updateData(state, myId);

			//选择合适的策略
			strategyManager.selectStrategy();

			//初始化攻击策略
			strategyManager.initAttackStrategy();
			
			var attackId:int = behaviorCompute.getAttackId();

			//仇恨降低
			var i:int = 0;
			for (i = 0; i < 6; i++)
			{
				stateData.attackMeDic[i]--;
				if (stateData.attackMeDic[i] < 0)
				{
					stateData.attackMeDic[i] = 0;
				}
			}
			
			for (i = 0; i < 6; i++)
			{
				var enmityRecord:EnmityRecord = stateData.enmityRecordDic[i];
				enmityRecord.preTurnAttackNum = 0;
			}

			attackOrderAnalysis.canAttackNum--;
			if(attackOrderAnalysis.canAttackNum > 0)
			{
				logger("【我还能一次】");
			}
			
			return attackId;
		}

		/**
		 * 	//在你升级时会被调用。前两参数同上。第三参数表示这是否是因为击杀而获得的升级奖励
		 //在一场战斗中，你已经死亡或者已经胜利不会继续被调用。
		 //isKillUpgrade表示是否是击杀升级。击杀升级时，会先增加50点hp，之后再调用这个函数。
		 //返回值：一个整形。
		 //返回4：提高4点攻击
		 //返回3：提高3点防守
		 //返回2：提高2点速度
		 //返回1：提高1点三围（三种属性）
		 //返回其他值视为放弃这次升级。
		 **/
		public function onUpgrade(state:Array, myId:int, isKillUpgrade:Boolean):int
		{
			logger(JSON.stringify(state)+",myId:"+myId+",isKillUpgrade:"+isKillUpgrade);
			//更新数据
			stateData.updateData(state, myId);

			//选择合适的策略
			strategyManager.selectStrategy();
			
			//初始化防御策略
			strategyManager.initDefenseStrategy();

			var upgradeId:int = behaviorCompute.getUpgradeId();

			return upgradeId;
		}

		//每当有人发动攻击时被调用，包括自己的攻击。state是攻击前的状态
		//收集数据可能对连续战斗的下一场有用，即使你已经挂掉了，也会被触发。
		//参数attcker，攻击的发动者。
		//参数target，攻击的承受者。
		public function onAnyoneAttack(state:Array, myId:int, attackerId:int, targetId:int):void
		{
			var attacker:Player = stateData.playerDic[attackerId];
			var target:Player = stateData.playerDic[targetId];
			target.hp = target.hp - attacker.attackDamage(target);
			if (target.hp == 0)
			{
				logger("【" + targetId + "号被击杀！】");
			}

			//记录谁打我
			if (targetId == myId)
			{
				stateData.attackMeDic[attackerId]++;
			}
			if(attackerId == myId)
			{
				//记录我攻击了谁
				stateData.attackPlayerIdList.push({targetId: targetId, turnIndex: stateData.turnIndex});
			}

			var enmityRecord:EnmityRecord = stateData.enmityRecordDic[targetId];
			enmityRecord.attackDic[attackerId]++;
			enmityRecord.preTurnAttackNum++;

			attackMaxAnalysis.onAnyoneAttack(state, myId, attackerId, targetId);
		}

		//每当有人升级时被调用，包括自己的升级。state是升级前的状态。
		//收集数据可能对连续战斗的下一场有用，即使你已经挂掉了，也会被触发。
		//isKillUpgrade表示是否是击杀升级。击杀升级时，会先增加50点hp，之后再调用这个函数。
		//如果有人放弃了升级（会有吗？），upgradeType可能是1~4之外的数字。
		public function onAnyoneUpgrade(state:Array, myId:int, upgraderId:int, upgradeType:int):void
		{
			// TODO Auto Generated method stub

		}

		//通知一场战斗开始
		//在连续战斗测胜率的过程中，不会重新加载swf，所以可以在这里初始化一些变量。
		//在此时，你的id会重新分配。
		public function onBattleStart(myId:int):void
		{
			//清空被打记录
			stateData.attackMeDic = new Dictionary();
			stateData.attackMeDic[0] = 0;
			stateData.attackMeDic[1] = 0;
			stateData.attackMeDic[2] = 0;
			stateData.attackMeDic[3] = 0;
			stateData.attackMeDic[4] = 0;
			stateData.attackMeDic[5] = 0;

			stateData.turnIndex = 0;

			//初始化仇恨记录表格
			stateData.enmityRecordDic = new Vector.<EnmityRecord>();
			for (var i:int = 0; i < 6; i++)
			{
				var enmityRecord:EnmityRecord = new EnmityRecord(i);
				enmityRecord.preTurnAttackNum = 0;
				stateData.enmityRecordDic[enmityRecord.playerId] = enmityRecord;
				for (var j:int = 0; j < 6; j++)
				{
					enmityRecord.attackDic[j] = 0;
				}
			}
			
			attackMaxAnalysis.onBattleStart(myId);
		}

		//通知一场战斗结束
		//收集数据可能对连续战斗的下一场有用，即使你已经挂掉了，也会被触发。
		//为避免大家群殴胜率最高者导致胜率难以区分，这个函数的参数不会提供“谁是胜者”
		//参数totalBattles, 总计连续进行的战斗次数。
		//参数myVectories, 自己的胜场。
		public function onBattleFinish(totalBattles:int, myVectories:int):void
		{
			// TODO Auto Generated method stub

			attackMaxAnalysis.onBattleFinish(totalBattles, myVectories);
		}

		//通知回合开始。
		//收集数据可能对连续战斗的下一场有用，即使你已经挂掉了，也会被触发。
		public function onTurn(state:Array, myId:int):void
		{
			//更新数据
			stateData.updateData(state, myId);

			stateData.turnIndex++;

			attackOrderAnalysis.computeAttackOrder();

			var i:int = 0;
			//仇恨降低
			for (i = 0; i < 6; i++)
			{
				var enmityRecord:EnmityRecord = stateData.enmityRecordDic[i];
				for (var j:int = 0; j < 6; j++)
				{
					enmityRecord.attackDic[j]--;
					if (enmityRecord.attackDic[j] < 0)
					{
						enmityRecord.attackDic[j] = 0;
					}
				}
			}

		}

		//游戏开始时仅会被调用一次
		//gameMode是游戏模式（局数），players是有多少玩家参与游戏。
		public function onGameSet(gameMode:int, players:int):void
		{
			logger("clear");
		}

		//在每局开始时或有玩家阵亡导致玩家人数改变时被调用。
		//在多局游戏中，这个方法能让玩家大致了解正在与哪些对手作战。
		//livingMD5：仍生存玩家文件名的MD5值。
		//livingMD5的顺序并非与id一一对应，而是打乱的！因此你只能知道还有哪些人活着而不能知道他们的座次。
		//myMD5：我的文件名加密后的MD5值
		public function onPlayerNumChanged(state:Object, myId:int, livingMD5:Array, myMD5:String):void
		{
//			logger("【到底什么东西啊】");
//			logger(state);
		}
	}
}
